home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / pluginy Firefox / 8614 / 8614.xpi / chrome / extension.jar / content / utils / ImageLoader.js
Encoding:
JavaScript  |  2010-02-10  |  4.8 KB  |  163 lines

  1. Glydo.PrioritizedImageLoader = Prototype.Class.create(Glydo.EventSource,{
  2.         
  3.     initialize: function($super,sources_to_try,prefetch,options) {
  4.         $super();
  5.         this.options = options || {};
  6.         this.sources = sources_to_try;
  7.         this.fetch = prefetch;
  8.         this.waiting = false;
  9.         this.startPrefetch();
  10.     },
  11.  
  12.     startPrefetch: function() {
  13.         this.cancelled = false;
  14.         this.next = 0;
  15.         this.succeeded = false;
  16.         this.failed = false;
  17.         this.tryNextImage();
  18.     },
  19.  
  20.     completeFetch: function() {
  21.         this.fetch = null;
  22.         if (!this.done) {
  23.             this.tryNextImage();
  24.         }
  25.     },
  26.     
  27.     get done() {
  28.         return this.succeeded || this.failed;
  29.     },
  30.     
  31.     cancel: function() {
  32.         this.cancelled = true;
  33.         if (this.loader) {
  34.             this.loader.src = null;
  35.             delete this.loader;
  36.         }
  37.         this.next = 0;
  38.     },
  39.     
  40.     tryNextImage: function() {
  41.         if (this.cancelled) {
  42.             return;
  43.         }
  44.         if (this.waiting) {
  45.             return;
  46.         }
  47.         
  48.         if (this.next >= this.sources.length) {
  49.             this.failed = true;
  50.             this.fire('onImageLoadingFailure',this);
  51.             return;
  52.         }
  53.         
  54.         if ((this.fetch !== null) && this.next >= this.fetch) {
  55.             return;
  56.         }
  57.  
  58.         
  59.         var loader = new Image();
  60.  
  61.         var me = this;
  62.         loader.onload  = Prototype.F.bind(this.onLoadSuccess,this); 
  63.         loader.onerror = Prototype.F.bind(this.onLoadError,this);
  64.         loader.onabort = Prototype.F.bind(this.onLoadError,this);
  65.  
  66.         this.loader = loader;
  67.         this.cur = this.sources[this.next++];
  68.         if (typeof(this.cur) == "string") {
  69.             loader.src = this.cur;
  70.         } else {
  71.             loader.src = this.cur.url;
  72.         }
  73.         this.waiting = true;
  74.     },
  75.  
  76.     onLoadError: function()    {
  77.         delete this.loader;
  78.         this.waiting = false;
  79.         this.tryNextImage();
  80.     },
  81.  
  82.     onLoadSuccess: function() {
  83.         this.waiting = false;
  84.         if (this.cancelled) {
  85.             return;
  86.         }
  87.         if (this.cur.validation && Prototype.O.isFunction(this.cur.validation)) {
  88.             if (!this.cur.validation.call(this.cur,this.loader)) {
  89.                 this.onLoadError();
  90.                 return;
  91.             }
  92.         }
  93.         if (this.options.validation && Prototype.O.isFunction(this.options.validation)) {
  94.             if (!this.options.validation.call(this.cur,this.loader)) {
  95.                 this.onLoadError();
  96.                 return;
  97.             }
  98.         }
  99.         this.image = this.loader;
  100.         this.succeeded = true;
  101.         this.fire('onImageLoadingSuccess',this);
  102.     },
  103. });
  104.         
  105.  
  106. Glydo.BestThumbnailLoader = Prototype.Class.create(Glydo.PrioritizedImageLoader,{
  107.     initialize: function($super,targetWidth, targetHeight,thumbnailGroups,options) {
  108.         this.targetWidth = targetWidth;
  109.         this.targetHeight = targetHeight;
  110.         this.thumbnailGroups = thumbnailGroups;
  111.         var thumbnails_to_try = 
  112.             this.thumbnailGroups.map(this.prioritizeThumbnails,this).reduce(
  113.                 function (a,b) { return a.concat(b); },[]);
  114.         var prefetch = null;
  115.         for (var i = 0; i < thumbnails_to_try.length; ++i) {
  116.             if (thumbnails_to_try[i].lazy) {
  117.                 prefetch = i;
  118.             }
  119.         }
  120.         thumbnails_to_try = Prototype.A.pluck(thumbnails_to_try,"thumbnail");
  121.         $super(thumbnails_to_try,prefetch,options);
  122.     },
  123.  
  124.     prioritizeThumbnails: function(thumbnails) {
  125.         var thumbnailsWithPenalties = thumbnails.map(
  126.             function (thumbnail) {
  127.                 var xFactor = this.targetWidth / thumbnail.width;
  128.                 var yFactor = this.targetHeight / thumbnail.height;
  129.                 var factor = Math.max(Math.min(xFactor,yFactor,Glydo.BestThumbnailLoader.Consts.MAX_THUMBNAIL_SCALING_FACTOR),Glydo.BestThumbnailLoader.Consts.MIN_THUMBNAIL_SCALING_FACTOR);
  130.                 var resultWidth = factor * thumbnail.width;
  131.                 var resultHeight = factor * thumbnail.height;
  132.                 var overflowArea = 0;
  133.                 var underfillArea = 0;
  134.                 if (resultWidth > this.targetWidth) {
  135.                     overflowArea += (resultWidth - this.targetWidth) * resultHeight;
  136.                 } else {
  137.                     underfillArea += (this.targetWidth - resultWidth) * this.targetHeight;
  138.                 }
  139.                 if (resultHeight > this.targetHeight) {
  140.                     overflowArea += (resultHeight - this.targetHeight) * Math.min(resultWidth,this.targetWidth);
  141.                 } else {
  142.                     underfillArea += (this.targetHeight - resultHeight) * Math.min(resultWidth,this.targetWidth);
  143.                 }
  144.                 var areaPenalty = (
  145.                         Glydo.BestThumbnailLoader.Consts.THUMBNAIL_UNDERFILL_PENALTY*underfillArea + 
  146.                         Glydo.BestThumbnailLoader.Consts.THUMBNAIL_OVERFLOW_PENALTY*overflowArea) / (this.targetWidth * this.targetHeight);
  147.                 var factorPenalty = (factor > 1 ? 
  148.                         Math.log(factor) / Math.log(Glydo.BestThumbnailLoader.Consts.MAX_THUMBNAIL_SCALING_FACTOR) :
  149.                         Math.log(factor) / Math.log(Glydo.BestThumbnailLoader.Consts.MIN_THUMBNAIL_SCALING_FACTOR));
  150.                 var penalty = areaPenalty + factorPenalty;
  151.                 return ({ penalty: penalty, thumbnail: thumbnail, lazy: !!thumbnail.lazy});
  152.             },this);
  153.         return thumbnailsWithPenalties.sort(function(a,b) { return a.penalty - b.penalty; });
  154.     },
  155. });
  156.  
  157. Glydo.BestThumbnailLoader.Consts = {
  158.         MAX_THUMBNAIL_SCALING_FACTOR: 1.1,
  159.         MIN_THUMBNAIL_SCALING_FACTOR: 0.1,
  160.         THUMBNAIL_UNDERFILL_PENALTY: 3.0,
  161.         THUMBNAIL_OVERFLOW_PENALTY: 1.0,
  162. };
  163.